package pokpok.domaine;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.TreeMap;

import pokpok.dao.JoueurDAO;

public class JoueurStat {

	private Joueur joueur;

	private Integer nbParties;
	private Integer nbPayees;
	private Integer nbHU;
	private Integer nbVictoires;
	private Integer nbRecaves;
	private Integer nbAddon;
	private Integer totalMise;
	private Integer totalGain;

	private Detail detail;

	public JoueurStat(Joueur joueur, List<Resultat> resultats,
			boolean avecDetail) {
		if (avecDetail) {
			detail = new Detail();
			detail.setBestGain(new ArrayList<Tournoi>());
			detail.setWorstNet(new ArrayList<Tournoi>());
			detail.setBestNet(new ArrayList<Tournoi>());
			detail.setBestMise(new ArrayList<Tournoi>());
			detail.setStatsHU(new HashSet<StatHU>());
			detail.initPositions();
		}
		this.joueur = joueur;
		nbParties = 0;
		nbPayees = 0;
		nbHU = 0;
		nbVictoires = 0;
		nbRecaves = 0;
		nbAddon = 0;
		totalMise = 0;
		totalGain = 0;
		if (resultats != null) {
			nbParties = resultats.size();
			for (Resultat resultat : resultats) {
				if (avecDetail) {
					detail.getPositions().put(
							resultat.getPosition(),
							1 + detail.getPositions().get(
									resultat.getPosition()));
					if (detail.getBestGainValue() == null
							|| resultat.getGain() > detail.getBestGainValue()) {
						detail.setBestGainValue(resultat.getGain());
						detail.setBestGain(new ArrayList<Tournoi>());
						detail.getBestGain().add(resultat.getTournoi());
					} else if (resultat.getGain() == detail.getBestGainValue()) {
						detail.getBestGain().add(resultat.getTournoi());
					}
					Tournoi t = resultat.getTournoi();
					Integer mise = t.getBuyin()
							+ (resultat.getNbRecaves() * t.getRecave());
					if (resultat.isAddon()) {
						mise = mise + t.getAddon();
					}
					if (detail.getBestMiseValue() == null
							|| mise > detail.getBestMiseValue()) {
						detail.setBestMiseValue(mise);
						detail.setBestMise(new ArrayList<Tournoi>());
						detail.getBestMise().add(resultat.getTournoi());
					} else if (mise == detail.getBestMiseValue()) {
						detail.getBestMise().add(resultat.getTournoi());
					}

					Integer net = resultat.getGain() - mise;

					if (detail.getBestNetValue() == null
							|| net > detail.getBestNetValue()) {
						detail.setBestNetValue(net);
						detail.setBestNet(new ArrayList<Tournoi>());
						detail.getBestNet().add(resultat.getTournoi());
					} else if (net == detail.getBestNetValue()) {
						detail.getBestNet().add(resultat.getTournoi());
					}

					if (detail.getWorstNetValue() == null
							|| net < detail.getWorstNetValue()) {
						detail.setWorstNetValue(net);
						detail.setWorstNet(new ArrayList<Tournoi>());
						detail.getWorstNet().add(resultat.getTournoi());
					} else if (net == detail.getWorstNetValue()) {
						detail.getWorstNet().add(resultat.getTournoi());
					}
				}
				if (resultat.getGain() > 0) {
					nbPayees++;
				}
				if (resultat.getPosition() <= 2) {
					if (avecDetail) {
						JoueurDAO jDAO = new JoueurDAO();
						Joueur adversaire = jDAO.findAdversaire(joueur,
								resultat.getTournoi());
						StatHU shu = detail
								.findOrCreateByAdversaire(adversaire);
						shu.addHU();
						if (resultat.getPosition() == 1) {
							shu.addVictoire();
						}
					}
					nbHU++;
					if (resultat.getPosition() == 1) {
						nbVictoires++;
					}
				}
				nbRecaves = nbRecaves + resultat.getNbRecaves();
				totalMise = totalMise + resultat.getTournoi().getBuyin();
				totalMise = totalMise
						+ (resultat.getNbRecaves() * resultat.getTournoi()
								.getRecave());
				if (resultat.isAddon()) {
					nbAddon++;
					totalMise = totalMise + resultat.getTournoi().getAddon();
				}
				totalGain = totalGain + resultat.getGain();
			}
		}
	}

	public String getLibelle() {
		String retour = "";
		String pseudoLib = joueur.getPseudo() == null ? "" : joueur.getPseudo();
		String nomLib = joueur.getNom() == null ? "" : joueur.getNom();
		String prenomLib = joueur.getPrenom() == null ? "" : joueur.getPrenom();
		if (!"".equals(pseudoLib)) {
			retour = retour + pseudoLib;
			if (!"".equals(prenomLib) || !"".equals(nomLib)) {
				retour = retour + " (" + prenomLib + " " + nomLib + ")";
			}
			return retour;
		} else {
			retour = retour + prenomLib + " " + nomLib;
			return retour;
		}
	}

	public String getPartPayees() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = nbPayees.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("##.##%");
		return format.format(d);
	}

	public String getPartHU() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = nbHU.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("##.##%");
		return format.format(d);
	}

	public String getPartVictoires() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = nbVictoires.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("##.##%");
		return format.format(d);
	}

	public String getPartVictoiresHU() {
		if (nbHU == null || nbHU == 0) {
			return "";
		}
		Double d = nbVictoires.doubleValue() / nbHU.doubleValue();
		DecimalFormat format = new DecimalFormat("##.##%");
		return format.format(d);
	}

	public String getNet() {
		Integer result = totalGain - totalMise;
		if (result < 0) {
			return "<span class=\"negatif\">" + result + "</span>";
		} else {
			return "<span class=\"positif\">+" + result + "</span>";
		}
	}

	public String getGrade() {
		Integer net = totalGain - totalMise;
		return Grade.getGrade(net).getNom();
	}

	public List<Grade> getGrades() {
		return Arrays.asList(Grade.values());
	}

	public Integer getNetInteger() {
		return totalGain - totalMise;
	}

	public String getMoyenneRecave() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = nbRecaves.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("##.##");
		return format.format(d);
	}

	public String getMoyenneAddon() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = nbAddon.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("#.##");
		return format.format(d);
	}

	public String getMoyenneMise() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = totalMise.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("####.##");
		return format.format(d);
	}

	public String getMoyenneGain() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Double d = totalGain.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("####.##");
		return format.format(d);
	}

	public String getMoyenneNet() {
		if (nbParties == null || nbParties == 0) {
			return "";
		}
		Integer result = totalGain - totalMise;
		Double d = result.doubleValue() / nbParties.doubleValue();
		DecimalFormat format = new DecimalFormat("##.##");
		if (result < 0) {
			return "<span class=\"negatif\">" + format.format(d) + "</span>";
		} else {
			return "<span class=\"positif\">+" + format.format(d) + "</span>";
		}
	}

	public Integer getNbParties() {
		return nbParties;
	}

	public void setNbParties(Integer nbParties) {
		this.nbParties = nbParties;
	}

	public Integer getNbPayees() {
		return nbPayees;
	}

	public void setNbPayees(Integer nbPayees) {
		this.nbPayees = nbPayees;
	}

	public Integer getNbHU() {
		return nbHU;
	}

	public void setNbHU(Integer nbHU) {
		this.nbHU = nbHU;
	}

	public Integer getNbVictoires() {
		return nbVictoires;
	}

	public void setNbVictoires(Integer nbVictoires) {
		this.nbVictoires = nbVictoires;
	}

	public Integer getNbRecaves() {
		return nbRecaves;
	}

	public void setNbRecaves(Integer nbRecaves) {
		this.nbRecaves = nbRecaves;
	}

	public Integer getNbAddon() {
		return nbAddon;
	}

	public void setNbAddon(Integer nbAddon) {
		this.nbAddon = nbAddon;
	}

	public Integer getTotalMise() {
		return totalMise;
	}

	public void setTotalMise(Integer totalMise) {
		this.totalMise = totalMise;
	}

	public Integer getTotalGain() {
		return totalGain;
	}

	public void setTotalGain(Integer totalGain) {
		this.totalGain = totalGain;
	}

	public Detail getDetail() {
		return detail;
	}

	public void setDetail(Detail detail) {
		this.detail = detail;
	}

}
